package cn.wujiangbo.controller.app;

import cn.wujiangbo.annotation.IgnoreAuth;
import cn.wujiangbo.constants.SystemConstants;
import cn.wujiangbo.domain.app.AppUser;
import cn.wujiangbo.dto.UserToken;
import cn.wujiangbo.exception.MyException;
import cn.wujiangbo.result.PageList;
import cn.wujiangbo.service.app.AppUserService;
import cn.wujiangbo.query.app.AppUserQuery;
import cn.wujiangbo.controller.base.BaseController;
import cn.wujiangbo.util.DateUtils;
import cn.wujiangbo.result.JSONResult;
import cn.wujiangbo.result.PageList;
import cn.wujiangbo.util.IdUtils;
import cn.wujiangbo.util.MyTools;
import cn.wujiangbo.util.RedisCache;
import cn.wujiangbo.vo.LoginSuccessVo;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * APP用户信息表 API接口
 *
 * @Author 波波老师(weixin : javabobo0513)
 */
@RestController
@RequestMapping("/appUser")
@Api(value = "/appUser", tags = {"APP用户信息表 API接口"})
public class AppUserController extends BaseController {

    @Autowired
    public AppUserService appUserService;

    @Resource
    public RedisCache redisCache;

    @Value("${easyjava.userDefaultAvatarPath}")
    public String userDefaultAvatarPath;

    /**
     * 新增数据到【APP用户信息表】
     *
     * @author 波波老师(weixin : javabobo0513)
     */
    @PostMapping(value = "/save")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "AppUser", name = "appUser", value = "")
    })
    @ApiOperation(value = "新增数据到【APP用户信息表】", notes = "新增数据到【APP用户信息表】", httpMethod = "POST")
    public JSONResult save(@RequestBody AppUser appUser) {
        appUser.setRegisterTime(DateUtils.getCurrentLocalDateTime());//设置注册时间
        appUserService.save(appUser);
        return JSONResult.success(true);
    }

    /**
     * 修改【APP用户信息表】表数据
     *
     * @author 波波老师(weixin : javabobo0513)
     */
    @PostMapping(value = "/update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "AppUser", name = "appUser", value = "")
    })
    @ApiOperation(value = "修改【APP用户信息表】表数据", notes = "修改【APP用户信息表】表数据", httpMethod = "POST")
    public JSONResult update(@RequestBody AppUser appUser) {
        appUser.setUpdateTime(DateUtils.getCurrentLocalDateTime());
        appUser.setUpdateUserName(getCurrentUserRealName());
        appUserService.updateById(appUser);
        return JSONResult.success(true);
    }

    /**
     * 批量删除【APP用户信息表】数据
     *
     * @author 波波老师(weixin : javabobo0513)
     */
    @PostMapping(value = "/batchDelete")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "AppUserQuery", name = "query", value = "")
    })
    @ApiOperation(value = "批量删除【APP用户信息表】数据", notes = "批量删除【APP用户信息表】数据", httpMethod = "POST")
    public JSONResult batchDelete(@RequestBody AppUserQuery query) {
        //批量删除数据库数据
        appUserService.removeByIds(Arrays.asList(query.getIds()));
        return JSONResult.success(true);
    }

    /**
     * 单个删除【APP用户信息表】数据
     *
     * @author 波波老师(weixin : javabobo0513)
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "long", name = "id", value = "")
    })
    @ApiOperation(value = "单个删除【APP用户信息表】数据", notes = "单个删除【APP用户信息表】数据", httpMethod = "DELETE")
    @DeleteMapping("/singleDelete/{id}")
    public JSONResult batchDelete(@PathVariable("id") Long id) {
        //单个删除数据库数据
        appUserService.removeById(id);
        return JSONResult.success(true);
    }

    /**
     * 根据ID查询【APP用户信息表】详情数据
     *
     * @author 波波老师(weixin : javabobo0513)
     */
    @GetMapping(value = "/{id}")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "long", name = "id", value = "")
    })
    @ApiOperation(value = "根据ID查询【APP用户信息表】详情数据", notes = "根据ID查询【APP用户信息表】详情数据", httpMethod = "GET")
    public JSONResult get(@PathVariable("id") Long id) {
        return JSONResult.success(appUserService.getById(id));
    }

    /**
     * 查询【APP用户信息表】所有数据（不分页）
     *
     * @author 波波老师(weixin : javabobo0513)
     */
    @GetMapping(value = "/list")
    @ApiOperation(value = "查询【APP用户信息表】所有数据（不分页）", notes = "查询【APP用户信息表】所有数据（不分页）", httpMethod = "GET")
    public JSONResult list() {
        List<AppUser> list = appUserService.list(null);
        return JSONResult.success(list);
    }

    /**
     * 查询【APP用户信息表】数据（分页）
     *
     * @param query 查询对象
     * @return PageList 分页对象
     * @author 波波老师(weixin : javabobo0513)
     */
    @PostMapping(value = "/pagelist")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "AppUserQuery", name = "query", value = "查询对象")
    })
    @ApiOperation(value = "查询【APP用户信息表】数据（分页）", notes = "查询【APP用户信息表】数据（分页）", httpMethod = "POST")
    public JSONResult pagelist(@RequestBody AppUserQuery query) {
        Page<AppUser> page = appUserService.selectMySqlPage(query);
        return JSONResult.success(new PageList<>(page.getTotal(), page.getRecords()));
    }

    /***********************************************************************************
     以上代码是自动生成的
     自己写的代码放在下面
     ***********************************************************************************/

    /**
     * APP登录接口-短信验证码登录
     */
    @IgnoreAuth
    @PostMapping(value = "/smsLogin")
    public JSONResult smsLogin(@RequestBody AppUser appUser) {
        if (!MyTools.hasLength(appUser.getLoginName())) {
            throw new MyException("手机号不能为空！");
        }
        //根据账号查询数据库用户信息
        QueryWrapper<AppUser> queryWrapper = new QueryWrapper();
        queryWrapper.eq("login_name", appUser.getLoginName());
        AppUser one = appUserService.getOne(queryWrapper);
        if (one == null) {
            throw new MyException("手机号不存在！");
        }

        if (!MyTools.hasLength(appUser.getSmsCode())) {
            throw new MyException("短信验证码不能为空！");
        }

        String smsRedisCode = redisCache.getCacheObject(SystemConstants.TOKEN_PHONE_KEY + appUser.getLoginName());
        if (!MyTools.hasLength(smsRedisCode)) {
            throw new MyException("短信验证码已过期！");
        }
        if (!appUser.getSmsCode().equals(smsRedisCode)) {
            throw new MyException("短信验证码错误！");
        }

        //封装返回值
        LoginSuccessVo vo = new LoginSuccessVo();
        handleUserInfo(one, vo);
        return JSONResult.success(vo);
    }

    //处理用户信息
    public void handleUserInfo(AppUser one, LoginSuccessVo vo) {
        //检查用户状态,用户状态（1：正常；2：限制登录）
        if (one.getUserStatus() == 2) {
            throw new MyException("抱歉，您已被限制登录" + (MyTools.hasLength(one.getUserError()) ? "，原因：" + one.getUserError() : "！"));
        }
        //登录成功，记录用户最后登录时间等信息
        one.setLastLoginTime(DateUtils.getCurrentLocalDateTime());
        appUserService.updateById(one);
        //登录密码正确，现在给前端颁发token
        //用户信息存Redis的key值
        String redisToken = IdUtils.fastSimpleUUID();
        UserToken userToken = new UserToken();
        userToken.setId(one.getId());
        userToken.setNickName(one.getNickName());
        redisCache.setCacheObject(SystemConstants.LOGIN_TOKEN_KEY_APP + redisToken,
                JSONObject.toJSONString(userToken), SystemConstants.TOKEN_REDIS_ALIVE_TIME, TimeUnit.HOURS);
        //封装返回值
        vo.setToken(redisToken);
        vo.setAppUser(one);
    }

    /**
     * APP端登录-发送短信验证码
     */
    @IgnoreAuth
    @GetMapping(value = "/sendSmsCode/{phone}")
    public JSONResult sendSmsCode(@PathVariable("phone") String phone) {
        if (!MyTools.hasLength(phone)) {
            throw new MyException("手机号不能为空！");
        }
        //根据账号查询数据库用户信息
        QueryWrapper<AppUser> queryWrapper = new QueryWrapper();
        queryWrapper.eq("login_name", phone);
        AppUser one = appUserService.getOne(queryWrapper);
        if (one == null) {
            throw new MyException("手机号不存在！");
        }

        String randomCode = MyTools.getRandomNum(6);
        //两小时
        redisCache.setCacheObject(SystemConstants.TOKEN_PHONE_KEY + phone, randomCode, SystemConstants.TOKEN_REDIS_ALIVE_TIME, TimeUnit.HOURS);
        String msg = "【宝贝淘】您的验证码是：" + randomCode + "，两小时内有效，请及时使用！";
        Map<String, String> map = new HashMap<>();
        map.put("msg", msg);
        map.put("code", randomCode);
        return JSONResult.success(map, false);
    }

    /**
     * APP端注册-发送短信验证码
     */
    @IgnoreAuth
    @GetMapping(value = "/sendSmsCodeRegister/{phone}")
    public JSONResult sendSmsCodeRegister(@PathVariable("phone") String phone) {
        if (!MyTools.hasLength(phone)) {
            throw new MyException("手机号不能为空！");
        }
        //根据账号查询数据库用户信息
        QueryWrapper<AppUser> queryWrapper = new QueryWrapper();
        queryWrapper.eq("login_name", phone);
        AppUser one = appUserService.getOne(queryWrapper);
        if (one != null) {
            throw new MyException("手机号已存在，可直接登录！");
        }

        String randomCode = MyTools.getRandomNum(6);
        //两小时
        redisCache.setCacheObject(SystemConstants.TOKEN_PHONE_KEY_REGISTER + phone, randomCode, SystemConstants.TOKEN_REDIS_ALIVE_TIME, TimeUnit.HOURS);
        String msg = "【宝贝淘】您的验证码是：" + randomCode + "，两小时内有效，请及时使用！";
        Map<String, String> map = new HashMap<>();
        map.put("msg", msg);
        map.put("code", randomCode);
        return JSONResult.success(map, false);
    }

    /**
     * APP注册接口
     */
    @IgnoreAuth
    @PostMapping(value = "/register")
    public JSONResult register(@RequestBody AppUser appUser) {
        if (!MyTools.hasLength(appUser.getLoginName())) {
            throw new MyException("账号不能为空！");
        }
        //查询手机号是否被注册
        QueryWrapper<AppUser> queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_phone", appUser.getLoginName())
                .or()
                .eq("login_name", appUser.getLoginName());
        AppUser one = appUserService.getOne(queryWrapper);
        if (one != null) {
            throw new MyException("账号已被注册，请更换！");
        }

        if (!MyTools.hasLength(appUser.getSmsCode())) {
            throw new MyException("短信验证码不能为空！");
        }

        String smsRedisCode = redisCache.getCacheObject(SystemConstants.TOKEN_PHONE_KEY_REGISTER + appUser.getLoginName());
        if (!MyTools.hasLength(smsRedisCode)) {
            throw new MyException("短信验证码已过期！");
        }
        if (!appUser.getSmsCode().equals(smsRedisCode)) {
            throw new MyException("短信验证码错误！");
        }

        //字段赋值
        appUser.setLoginName(appUser.getLoginName());
        appUser.setLoginPass(appUser.getLoginPass());
        appUser.setUserPhone(appUser.getLoginName());
        appUser.setUserImg(userDefaultAvatarPath);//头像
        appUser.setNickName(MyTools.getNickName());//随机昵称
        appUser.setUserStatus(1);//用户状态（1：正常；2：限制登录）
        appUser.setRegisterTime(DateUtils.getCurrentLocalDateTime());//账号注册时间
        appUser.setUserMoney(new BigDecimal(5));
        //数据入库
        appUserService.save(appUser);
        return JSONResult.successMessage(true, "注册成功，快去登录吧！");
    }

    /**
     * 获取当前登录人的个人资料
     */
    @GetMapping(value = "/getUserInfo")
    public JSONResult getUserInfo() {
        return JSONResult.success(appUserService.getById(getAppUserId()));
    }
}